package fr.umlv.m2.uwp2011.web.client.common;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import fr.umlv.m2.uwp2011.service.user.IUserService;
import fr.umlv.m2.uwp2011.service.user.IUserServiceAsync;
import fr.umlv.m2.uwp2011.service.user.UserDTO;
import fr.umlv.m2.uwp2011.web.client.Application;
import fr.umlv.m2.uwp2011.web.client.Session;

public class LoginTemplate extends Composite {
	/**
	 * The session.
	 */
	private Session session;

	/**
	 * The title login page.
	 */
	private final Label titlePage;

	/**
	 * The login form.
	 */
	private final FlexTable form;
	/**
	 * The form login field. 
	 */
	private final TextBox loginField;
	/**
	 * The form password field.
	 */
	private final PasswordTextBox passwordField;
	/**
	 * The form button submit.
	 */
	private final Button loginButton;
	/**
	 * The error label.
	 */
	private final Label errorLabel;

	/**
	 * The login panel page.
	 */
	private final VerticalPanel loginPanel;

	/**
	 * The user service.
	 */
	private final IUserServiceAsync userService;

	public LoginTemplate(Session session) {
	  /****************************** Widgets Creation ******************************/
		this.session = session;

		this.titlePage = new Label();
		this.form = new FlexTable();
		this.loginField = new TextBox();
		this.passwordField = new PasswordTextBox();
		this.loginButton = new Button("Valider");
		this.errorLabel = new Label();
		this.loginPanel = new VerticalPanel();
		this.userService = GWT.create(IUserService.class);

		/*************************** Widgets initialization ***************************/
		this.titlePage.setText("University Web Portal");

		this.form.setText(0, 0, "Authentification");
		this.form.setText(1, 0, "Identifiant :");
		this.form.setWidget(1, 1, this.loginField);
		this.form.setText(2, 0, "Mot de passe :");
		this.form.setWidget(2, 1, this.passwordField);
		this.form.setWidget(3, 1, this.loginButton);
		this.form.setWidget(4, 0, this.errorLabel);

		this.errorLabel.setText("Utilisateur inconnu ou mot de passe incorrect.");
		this.errorLabel.setVisible(false);

		/******************************** Widgets style *******************************/
		this.titlePage.setStyleName("loginTitle");

		this.form.setWidth("411px");
		this.form.setStyleName("loginForm");
		this.form.setCellSpacing(2);

		this.form.getFlexCellFormatter().setColSpan(0, 0, 2);
		this.form.getFlexCellFormatter().setHorizontalAlignment(0, 0, HasAlignment.ALIGN_CENTER);
		this.form.getFlexCellFormatter().setHeight(0, 0, "22px");
		this.form.getFlexCellFormatter().setStyleName(0, 0, "loginTitleForm");

		this.form.getFlexCellFormatter().setWidth(1, 0, "160px");
		this.form.getFlexCellFormatter().setHorizontalAlignment(1, 0, HasAlignment.ALIGN_RIGHT);
		this.form.getFlexCellFormatter().setStyleName(1, 0, "loginItemFormTopSpacing");
		this.form.getFlexCellFormatter().setStyleName(1, 1, "loginItemFormTopSpacing");

		this.form.getFlexCellFormatter().setWidth(1, 0, "160px");
		this.form.getFlexCellFormatter().setHorizontalAlignment(2, 0, HasAlignment.ALIGN_RIGHT);

		this.form.getFlexCellFormatter().setStyleName(3, 1, "loginButtonForm");

		this.form.getFlexCellFormatter().setColSpan(4, 0, 2);
		this.form.getFlexCellFormatter().setHorizontalAlignment(4, 0, HasAlignment.ALIGN_CENTER);
		this.form.getFlexCellFormatter().setHeight(4, 0, "30px");
		this.form.getFlexCellFormatter().setVerticalAlignment(4, 0, HasAlignment.ALIGN_BOTTOM);

		this.errorLabel.setStyleName("loginErrorLabel");

		this.loginPanel.setWidth("100%");
		this.loginPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);

		/******************************** Page building *******************************/
		this.loginPanel.add(titlePage);
		this.loginPanel.add(form);
		this.initWidget(loginPanel);

		/******************************* Action handler *******************************/
		KeyDownHandler keyDownHandler = new KeyDownHandler() {
			@Override
			public void onKeyDown(KeyDownEvent event) {
				if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER ) {
					loginUser();
				}
			}
		};

		loginField.addKeyDownHandler(keyDownHandler);		
		passwordField.addKeyDownHandler(keyDownHandler);

		loginButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				loginUser();
			}
		});
	}

	private void loginUser() {
		userService.getUser(loginField.getText(), passwordField.getText(), new AsyncCallback<UserDTO>() {    
			@Override
			public void onSuccess(UserDTO userDTO) {
				errorLabel.setVisible(false);

				String nextPage = Application.LOGIN_PAGE;

				if(userDTO.isTeacher()) {
					nextPage = Application.PROFESSOR_HOMEPAGE;
				} else if(userDTO.isStudent()) {
					nextPage = "studentPage";
				} else if(userDTO.isSecretary()) {
					nextPage = Application.SECRETARY_HOMEPAGE;
				} else if(userDTO.getLogin().equals("admin")) {
					nextPage = "adminPage";
				}

				session.setUser(userDTO);
				session.setCurrentPage(nextPage);
				
				// Pour plus de securite on va faire un SHA1 du login+password+dateInscription+heure.
				String key = Application.getSHA1(userDTO.getLogin());
				
				Application.redirect("../Application.html?gwt.codesvr=127.0.0.1:9997#" + nextPage + 
				    "?login=" + userDTO.getLogin() + 
				    "&key=" + key
				);
			}

			@Override
			public void onFailure(Throwable caught) {
				errorLabel.setVisible(true);
				loginField.setText("");
				passwordField.setText("");
			}
		});
	}
}
